<template>
  <div class="knowledge-map-container">
    <div class="page-header">
      <h1>思维导图</h1>
      <p>可视化知识结构，建立知识体系</p>
    </div>

    <div class="map-content">
      <div class="map-sidebar">
        <div class="sidebar-header">
          <h3>学科分类</h3>
        </div>

        <el-menu :default-active="currentSubject" class="subject-menu" @select="handleSubjectSelect">
          <el-menu-item v-for="subject in subjects" :key="subject.id" :index="subject.id.toString()">
            <el-icon>
              <component :is="subject.icon" />
            </el-icon>
            <span>{{ subject.name }}</span>
          </el-menu-item>
        </el-menu>
      </div>

      <div class="map-main">
        <div class="map-controls">
          <div class="search-box">
            <el-input v-model="searchKeyword" placeholder="搜索知识点..." prefix-icon="Search" clearable
              @input="handleSearch"></el-input>
          </div>

          <div class="view-controls">
            <el-radio-group v-model="viewMode" size="small">
              <el-radio-button label="mindmap">思维导图</el-radio-button>
              <el-radio-button label="tree">树形视图</el-radio-button>
            </el-radio-group>

            <!-- <el-tooltip content="重置视图" placement="top">
              <el-button size="small" @click="resetZoom">
                <el-icon><FullScreen /></el-icon>
              </el-button>
            </el-tooltip> -->

            <!-- 添加操作提示按钮 -->
            <el-tooltip content="操作帮助" placement="top">
              <el-button size="small" @click="showTips = !showTips">
                <el-icon>
                  <QuestionFilled />
                </el-icon>
              </el-button>
            </el-tooltip>
          </div>
        </div>

        <div class="map-visualization">
          <div v-if="loading" class="loading-container">
            <el-skeleton :rows="10" animated />
          </div>

          <div v-show="viewMode === 'mindmap'" class="mindmap-container">
            <div id="mindmap-container" ref="mindMapContainerRef" style="width:100%;height:100%;"></div>

            <!-- 操作提示 -->
            <transition name="fade">
              <div v-if="showTips" class="operation-tips">
                <div class="tips-header">
                  <h4>操作提示</h4>
                  <el-button type="text" @click="showTips = false">
                    <el-icon>
                      <Close />
                    </el-icon>
                  </el-button>
                </div>
                <ul>
                  <li><el-icon>
                      <Mouse />
                    </el-icon> 左键拖动：移动画布</li>
                  <li><el-icon>
                      <Position />
                    </el-icon> 鼠标滚轮：上下平移</li>
                  <li><el-icon>
                      <ZoomIn />
                    </el-icon> ctrl+滚轮：缩放视图</li>
                  <li><el-icon>
                      <Pointer />
                    </el-icon> 单击节点：查看详情</li>
                </ul>
              </div>
            </transition>
          </div>

          <div v-show="viewMode === 'tree'" class="tree-view">
            <el-tree :data="treeData" :props="defaultProps" :expand-on-click-node="false"
              :default-expanded-keys="[currentSubject]" node-key="id" highlight-current @node-click="handleNodeClick">
              <template #default="{ node, data }">
                <span class="tree-node">
                  <span>{{ node.label }}</span>
                  <span v-if="data.count" class="node-count">({{ data.count }})</span>
                </span>
              </template>
            </el-tree>
          </div>
        </div>
      </div>

      <div class="knowledge-detail" v-if="selectedNode">
        <div class="detail-header">
          <h3>{{ selectedNode.name }}</h3>
          <el-button size="small" @click="closeDetail">
            <el-icon>
              <Close />
            </el-icon>
          </el-button>
        </div>

        <div class="detail-content">
          <div class="detail-section">
            <h4>概述</h4>
            <p>{{ selectedNode.description }}</p>
          </div>

          <div class="detail-section" v-if="selectedNode.keyPoints && selectedNode.keyPoints.length">
            <h4>关键点</h4>
            <ul>
              <li v-for="(point, index) in selectedNode.keyPoints" :key="index">
                {{ point }}
              </li>
            </ul>
          </div>

          <div class="detail-section" v-if="selectedNode.relatedCourses && selectedNode.relatedCourses.length">
            <h4>相关课程</h4>
            <div class="related-courses">
              <el-card v-for="course in selectedNode.relatedCourses" :key="course.id" class="related-course-card"
                shadow="hover" @click="navigateToCourse(course.id)">
                <div class="course-info">
                  <div class="course-title">{{ course.title }}</div>
                  <div class="course-meta">
                    <el-rate v-model="course.rating" disabled text-color="#ff9900" size="14" />
                    <span class="course-students">{{ course.students }}人学习</span>
                  </div>
                </div>
              </el-card>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed, watch, nextTick, onUnmounted, shallowRef } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
import MindMap from 'simple-mind-map';
// 导入必要的插件
import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js';
import Watermark from 'simple-mind-map/src/plugins/Watermark.js';
import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js';
import Export from 'simple-mind-map/src/plugins/Export.js';
import Drag from 'simple-mind-map/src/plugins/Drag.js';
import Select from 'simple-mind-map/src/plugins/Select.js';
import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js';
import SearchPlugin from 'simple-mind-map/src/plugins/Search.js';
import {
  Search,
  ZoomIn,
  ZoomOut,
  FullScreen,
  Close,
  Mouse,
  Position,
  Pointer,
  QuestionFilled
} from '@element-plus/icons-vue';

// 注册插件
MindMap.usePlugin(MiniMap)
  .usePlugin(Watermark)
  .usePlugin(Drag)
  .usePlugin(KeyboardNavigation)
  .usePlugin(Export)
  .usePlugin(Select)
  .usePlugin(TouchEvent)
  .usePlugin(SearchPlugin);

const router = useRouter();
const store = useStore();

const currentSubject = ref('1'); // 默认选中数学
const viewMode = ref('mindmap'); // 默认使用思维导图视图
const searchKeyword = ref('');
const loading = ref(true);
const mindMap = ref(null);
const selectedNode = ref(null);
const showTips = ref(false);
const mindMapContainerRef = ref(null);
// 当前右键点击的节点
const currentNode = shallowRef(null);

// 学科列表
const subjects = [
  { id: 1, name: '数学', icon: 'DataAnalysis' },
  { id: 2, name: '物理', icon: 'Histogram' },
  { id: 3, name: '化学', icon: 'Monitor' },
  { id: 4, name: '生物', icon: 'Opportunity' },
  { id: 5, name: '语文', icon: 'Reading' },
  { id: 6, name: '英语', icon: 'ChatDotRound' }
];

// 知识点数据
const knowledgeData = {
  '1': {
    id: 1,
    name: '数学',
    children: [
      {
        id: 101,
        name: '代数',
        description: '代数是数学的一个主要分支，处理数学符号和处理这些符号的规则。',
        children: [
          {
            id: 10101,
            name: '方程式',
            description: '方程式是由一个或多个变量组成的等式，求解方程式就是找出使等式成立的变量值。',
            keyPoints: [
              '一元一次方程',
              '二元一次方程组',
              '一元二次方程'
            ],
            relatedCourses: [
              {
                id: 1,
                title: '初中代数基础',
                students: 1200,
                rating: 4.5
              },
              {
                id: 2,
                title: '高中代数进阶',
                students: 800,
                rating: 4.7
              }
            ]
          },
          {
            id: 10102,
            name: '函数',
            description: '函数是输入值与输出值之间的对应关系，是研究变量之间依赖关系的数学工具。',
            keyPoints: [
              '函数的定义域和值域',
              '函数的性质',
              '常见函数类型'
            ],
            relatedCourses: [
              {
                id: 3,
                title: '函数与图像',
                students: 950,
                rating: 4.6
              }
            ]
          }
        ]
      },
      {
        id: 102,
        name: '几何',
        description: '几何是研究空间关系和形状的数学分支。',
        children: [
          {
            id: 10201,
            name: '平面几何',
            description: '平面几何研究二维空间中的点、线、面等几何图形的性质。',
            keyPoints: [
              '三角形的性质',
              '四边形的性质',
              '圆的性质'
            ],
            relatedCourses: [
              {
                id: 4,
                title: '初中平面几何',
                students: 1100,
                rating: 4.4
              }
            ]
          },
          {
            id: 10202,
            name: '立体几何',
            description: '立体几何研究三维空间中的几何图形的性质。',
            keyPoints: [
              '多面体',
              '旋转体',
              '空间向量'
            ],
            relatedCourses: [
              {
                id: 5,
                title: '高中立体几何',
                students: 750,
                rating: 4.3
              }
            ]
          }
        ]
      }
    ]
  },
  '2': {
    id: 2,
    name: '物理',
    children: [
      {
        id: 201,
        name: '力学',
        description: '力学是研究物体运动规律和相互作用的物理学分支。',
        children: [
          {
            id: 20101,
            name: '牛顿力学',
            description: '牛顿力学是基于牛顿运动定律的经典力学体系。',
            keyPoints: [
              '牛顿三大定律',
              '万有引力定律',
              '动量守恒定律'
            ],
            relatedCourses: [
              {
                id: 6,
                title: '高中力学基础',
                students: 980,
                rating: 4.6
              }
            ]
          }
        ]
      }
    ]
  }
};

// 计算树形视图数据
const treeData = computed(() => {
  // 获取当前学科的数据
  const subjectData = knowledgeData[currentSubject.value];
  if (!subjectData) return [];

  // 转换为树形结构
  const convertToTreeData = (node) => {
    const treeNode = {
      id: node.id.toString(),
      label: node.name,
      children: []
    };

    // 添加子节点
    if (node.children && node.children.length) {
      treeNode.children = node.children.map(child => convertToTreeData(child));
      treeNode.count = treeNode.children.length;
    }

    return treeNode;
  };

  return [convertToTreeData(subjectData)];
});

// 树形视图配置
const defaultProps = {
  children: 'children',
  label: 'label'
};

// 处理树形视图节点点击
const handleNodeClick = (data) => {
  // 查找原始节点数据
  const findOriginalNode = (id, nodes) => {
    for (const node of nodes) {
      if (node.id.toString() === id) {
        console.log('原始节点数据:', node);
        return node;
      }
      if (node.children && node.children.length) {
        const found = findOriginalNode(id, node.children);
        if (found) {
          console.log('原始节点数据:', found);
          return found;
        }
      }
    }
    return null;
  };

  // 从当前学科数据中查找节点
  const originalNode = findOriginalNode(data.id, [knowledgeData[currentSubject.value]]);
  if (originalNode) {
    selectedNode.value = originalNode;
  }
};

// 处理思维导图节点点击
const handleMindMapNodeClick = (e, node) => {
  try {
    console.log('节点点击事件:', e);
    console.log('节点数据:', node);

    // 检查是否是DOM事件
    if (e instanceof Event && !node) {
      // 如果只有一个参数，且是事件对象，尝试从事件目标获取节点数据
      const target = e.target;
      console.log('点击目标:', target);

      // 从当前选中的节点获取数据
      const activeNodes = mindMap.value.renderer.activeNodeList;
      if (activeNodes && activeNodes.length > 0) {
        const activeNode = activeNodes[0];
        console.log('当前活动节点:', activeNode);

        // 从节点的自定义数据中获取原始数据
        if (activeNode._data && activeNode._data.originData) {
          selectedNode.value = activeNode._data.originData;
          console.log('设置选中节点:', selectedNode.value);
          return;
        }
      }

      console.error('无法从事件中获取节点数据');
      return;
    }

    // 如果有两个参数，第二个是节点数据
    if (node && node._data) {
      console.log('节点_data:', node._data);

      // 从节点的自定义数据中获取原始数据
      if (node._data.originData) {
        selectedNode.value = node._data.originData;
        console.log('设置选中节点:', selectedNode.value);
        return;
      }
    }

    console.error('节点数据不完整:', e);
  } catch (error) {
    console.error('处理节点点击失败:', error);
  }
};

// 转换数据为思维导图格式
const convertToMindMapData = (data) => {
  // 根节点
  const rootNode = {
    data: {
      text: data.name,
      originData: data // 存储原始数据
    },
    children: []
  };

  // 递归处理子节点
  const processChildren = (children, parentNode) => {
    if (!children || !children.length) return;

    children.forEach(child => {
      const childNode = {
        data: {
          text: child.name,
          originData: child, // 存储原始数据
          expand: true // 默认展开
        },
        children: []
      };

      parentNode.children.push(childNode);

      // 处理子节点的子节点
      if (child.children && child.children.length) {
        processChildren(child.children, childNode);
      }
    });
  };

  // 处理根节点的子节点
  if (data.children && data.children.length) {
    processChildren(data.children, rootNode);
  }

  return rootNode;
};

// 处理学科选择
const handleSubjectSelect = (subjectId) => {
  currentSubject.value = subjectId;
  selectedNode.value = null;

  if (viewMode.value === 'mindmap') {
    nextTick(() => {
      initMindMap();
    });
  }
};

// 处理视图模式切换
watch(viewMode, (newMode) => {
  if (newMode === 'mindmap') {
    nextTick(() => {
      initMindMap();
    });
  }
});

// 处理搜索
const handleSearch = () => {
  if (viewMode.value === 'mindmap' && mindMap.value) {
    // 在思维导图中搜索
    if (searchKeyword.value) {
      try {
        // 使用 simple-mind-map 的搜索方法
        const result = mindMap.value.searchNode(searchKeyword.value);
        console.log('搜索结果:', result);
      } catch (error) {
        console.error('搜索失败:', error);
      }
    }
  }
};

// 关闭详情面板
const closeDetail = () => {
  selectedNode.value = null;
};

// 导航到课程
const navigateToCourse = (courseId) => {
  router.push(`/courses/${courseId}`);
};

// 缩放相关方法
const zoomIn = () => {
  try {
    if (mindMap.value) {
      // 使用内置命令
      mindMap.value.execCommand('zoomIn');
    }
  } catch (error) {
    console.error('缩放失败:', error);
  }
};

const zoomOut = () => {
  try {
    if (mindMap.value) {
      // 使用内置命令
      mindMap.value.execCommand('zoomOut');
    }
  } catch (error) {
    console.error('缩放失败:', error);
  }
};

const resetZoom = () => {
  try {
    if (mindMap.value) {
      // 使用内置命令
      mindMap.value.execCommand('resetZoom');
    }
  } catch (error) {
    console.error('重置缩放失败:', error);
  }
};

// 初始化思维导图
const initMindMap = () => {
  loading.value = true;

  try {
    // 获取容器元素
    const container = mindMapContainerRef.value;
    if (!container) {
      console.error('思维导图容器元素不存在');
      loading.value = false;
      return;
    }

    // 清空容器
    container.innerHTML = '';

    // 获取当前学科的数据
    const subjectData = knowledgeData[currentSubject.value];
    if (!subjectData) {
      console.error('未找到学科数据');
      loading.value = false;
      return;
    }

    // 转换数据为思维导图格式
    const data = convertToMindMapData(subjectData);
    console.log('思维导图数据:', data);

    // 创建思维导图实例
    mindMap.value = new MindMap({
      el: container,
      data: data,
      layout: 'logicalStructure', // 逻辑结构布局
      theme: {
        background: '#f5f7fa',
        color: '#303133',
        lineColor: '#909399',
        lineWidth: 2,
        fontSize: 14,
        rootBackground: '#409EFF',
        rootColor: '#fff',
        secondNodeBackground: '#67C23A',
        secondNodeColor: '#fff',
        thirdNodeBackground: '#E6A23C',
        thirdNodeColor: '#fff'
      },
      enableFreeDrag: true, // 允许自由拖动
      watermark: {
        content: 'AI Study', // 水印内容
        opacity: 0.1 // 水印透明度
      }
    });

    // 注册节点点击事件
    mindMap.value.on('node_click', handleMindMapNodeClick);

    // 注册节点选择事件
    mindMap.value.on('node_active', (node) => {
      console.log('节点选中:', node);
      if (node && node._data && node._data.originData) {
        selectedNode.value = node._data.originData;
      }
    });

    // 完成加载
    loading.value = false;

    // 首次加载时显示操作提示
    if (!localStorage.getItem('mindMapTipsShown')) {
      showTips.value = true;
      localStorage.setItem('mindMapTipsShown', 'true');
    }
  } catch (error) {
    console.error('初始化思维导图失败:', error);
    loading.value = false;
  }
};

// 窗口大小变化处理
const handleResize = () => {
  if (mindMap.value) {
    try {
      // 调整思维导图大小
      mindMap.value.resize();
    } catch (error) {
      console.error('调整大小失败:', error);
    }
  }
};

// 组件挂载时
onMounted(() => {
  // 初始化思维导图
  if (viewMode.value === 'mindmap') {
    nextTick(() => {
      initMindMap();
    });
  }

  // 添加窗口大小变化监听
  window.addEventListener('resize', handleResize);
});

// 组件卸载时
onUnmounted(() => {
  // 移除窗口大小变化监听
  window.removeEventListener('resize', handleResize);

  // 销毁思维导图实例
  if (mindMap.value) {
    try {
      mindMap.value.destroy();
    } catch (error) {
      console.error('销毁思维导图实例失败:', error);
    }
    mindMap.value = null;
  }
});
</script>

<style lang="scss" scoped>
.knowledge-map-container {
  padding: 20px;
  max-width: 90%;
  margin: 0 auto;

  .page-header {
    margin-bottom: 20px;

    h1 {
      margin: 0 0 10px;
      font-size: 24px;
      color: #303133;
    }

    p {
      margin: 0;
      color: #606266;
    }
  }

  .map-content {
    display: flex;
    height: calc(100vh - 150px);
    border: 1px solid #ebeef5;
    border-radius: 4px;
    overflow: hidden;

    .map-sidebar {
      width: 200px;
      border-right: 1px solid #ebeef5;
      background-color: #fff;

      .sidebar-header {
        padding: 15px;
        border-bottom: 1px solid #ebeef5;

        h3 {
          margin: 0;
          font-size: 16px;
          color: #303133;
        }
      }

      .subject-menu {
        border-right: none;
      }
    }

    .map-main {
      flex: 1;
      display: flex;
      flex-direction: column;
      background-color: #fff;

      .map-controls {
        padding: 15px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid #ebeef5;

        .search-box {
          width: 250px;
        }

        .view-controls {
          display: flex;
          align-items: center;

          .zoom-controls {
            margin-left: 15px;
          }
        }
      }

      .map-visualization {
        flex: 1;
        position: relative;

        .loading-container {
          padding: 20px;
        }

        .mindmap-container {
          width: 100%;
          height: 100%;
          overflow: hidden;
          position: relative;

          .operation-tips {
            position: absolute;
            bottom: 20px;
            right: 20px;
            background-color: rgba(255, 255, 255, 0.95);
            border: 1px solid #ebeef5;
            border-radius: 4px;
            padding: 10px 15px;
            box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
            z-index: 100;

            .tips-header {
              display: flex;
              justify-content: space-between;
              align-items: center;
              margin-bottom: 8px;

              h4 {
                margin: 0;
                font-size: 14px;
                color: #303133;
              }
            }

            ul {
              margin: 0;
              padding-left: 20px;

              li {
                display: flex;
                align-items: center;
                margin-bottom: 5px;
                color: #606266;
                font-size: 12px;

                .el-icon {
                  margin-right: 5px;
                }
              }
            }
          }
        }

        .tree-view {
          padding: 20px;
          height: 100%;
          overflow: auto;

          .tree-node {
            display: flex;
            align-items: center;

            .node-count {
              margin-left: 5px;
              color: #909399;
              font-size: 12px;
            }
          }
        }
      }
    }

    .knowledge-detail {
      width: 300px;
      border-left: 1px solid #ebeef5;
      background-color: #f5f7fa;
      overflow-y: auto;

      .detail-header {
        padding: 15px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        border-bottom: 1px solid #ebeef5;
        background-color: #fff;

        h3 {
          margin: 0;
          font-size: 16px;
          color: #303133;
        }
      }

      .detail-content {
        padding: 15px;

        .detail-section {
          margin-bottom: 20px;

          h4 {
            margin: 0 0 10px;
            font-size: 14px;
            color: #303133;
          }

          p {
            margin: 0;
            color: #606266;
            line-height: 1.6;
          }

          ul {
            margin: 0;
            padding-left: 20px;

            li {
              color: #606266;
              line-height: 1.6;
            }
          }

          .related-courses {
            .related-course-card {
              margin-bottom: 10px;
              cursor: pointer;

              &:last-child {
                margin-bottom: 0;
              }

              .course-info {
                .course-title {
                  font-weight: 500;
                  margin-bottom: 5px;
                  color: #303133;
                }

                .course-meta {
                  display: flex;
                  align-items: center;
                  justify-content: space-between;

                  .course-students {
                    font-size: 12px;
                    color: #909399;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

// 添加淡入淡出动画
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

@media (max-width: 768px) {
  .map-content {
    flex-direction: column;

    .map-sidebar {
      width: 100%;
      border-right: none;
      border-bottom: 1px solid #ebeef5;
    }

    .knowledge-detail {
      width: 100%;
      border-left: none;
      border-top: 1px solid #ebeef5;
    }
  }
}
</style>